package com.rv.nats.resolver.param;

import com.rv.nats.annotation.TopicIndex;
import io.nats.client.Message;

import java.lang.reflect.Parameter;

/**
 * @author sundez
 * @version 1.1.3.7
 * @since 2025/6/12
 * 主题路径参数解析器
 * 用于解析方法参数中带有{@link TopicIndex}注解的参数
 * 该注解用于指定方法参数在主题路径中的位置
 * 例如：主题路径为"user.1.info"，则{@link TopicIndex}注解的值为1
 */
public class TopicIndexParameterResolver implements ParameterResolver {
    /**
     * 判断当前解析器是否支持对parameter的解析
     *
     * @param parameter 方法中反射的参数
     * @return 是否支持
     */
    @Override
    public boolean support(Parameter parameter) {
        return parameter.isAnnotationPresent(TopicIndex.class);
    }

    /**
     * 将message中的数据进行解析然后再返回
     *
     * @param message   {@link Message}
     * @param parameter {@link Parameter}
     * @return 解析后的数据
     */
    @Override
    public Object resolve(Message message, Parameter parameter) {
        String[] topics = message.getSubject().split("\\.");
        int index = parameter.getAnnotation(TopicIndex.class).value();
        if (index < 0 || topics.length <= index) {
            throw new IllegalArgumentException("主题路径参数解析错误, 主题路径为: " + message.getSubject() + ", 参数索引为: " + index);
        }
        String topic = topics[index];
        Class<?> type = parameter.getType();
        if (type == String.class) {
            return topic;
        }
        if (type == int.class || type == Integer.class) {
            return Integer.parseInt(topic);
        }
        if (type == long.class || type == Long.class) {
            return Long.valueOf(topic);
        }
        if (type == boolean.class || type == Boolean.class) {
            return Boolean.valueOf(topic);
        }
        if (type == float.class || type == Float.class) {
            return Float.valueOf(topic);
        }
        if (type == double.class || type == Double.class) {
            return Double.parseDouble(topic);
        }
        if (type == byte.class || type == Byte.class) {
            return Byte.parseByte(topic);
        }
        if (type == char.class || type == Character.class) {
            return topic.charAt(0);
        }
        if (type == short.class || type == Short.class) {
            return Short.valueOf(topic);
        }
        return topic;
    }
}
